package cn.xinfei.xdecision.thread;


import com.alibaba.fastjson.JSONObject;
import com.alibaba.ttl.threadpool.TtlExecutors;
import lombok.extern.slf4j.Slf4j;
import org.python.netty.util.concurrent.DefaultThreadFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;

@Slf4j
@Configuration
public class CustomerThreadPoolExecutorBuilder {

    public static RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy() {
        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            log.info("线程已满，执行拒绝策略callerRunsPolicy");
            throw new RejectedExecutionException("Task " + r.toString() + " rejected from " + e.toString());
        }
    };


    @Bean(name = "bizProcessorThreadPool")
    public ExecutorService bizProcessorThreadPool(@Qualifier("threadPoolPropertyProperty") ThreadPoolExecutorConfig threadPoolPropertyProperty) {
        log.info("bizProcessorThreadPool={}", JSONObject.toJSONString(threadPoolPropertyProperty));
        CustomerThreadPoolExecutor customerThreadPoolExecutor = new CustomerThreadPoolExecutor(threadPoolPropertyProperty);
        ExecutorService ttlExecutorService = TtlExecutors.getTtlExecutorService(customerThreadPoolExecutor);
        customerThreadPoolExecutor.allowCoreThreadTimeOut(threadPoolPropertyProperty.isAllowCoreThreadTimeOut());
        return ttlExecutorService;
    }


    @ConditionalOnProperty(name = "xdecision.decisionchallengethread.enable")
    @Bean(name = "decisionTableThreadPool")
    public ExecutorService decisionTableThreadPool(@Qualifier("decisionTableThreadPoolProperty") ThreadPoolExecutorConfig decisionTableThreadPoolProperty) {
        log.info("decisionTableThreadPool={}", JSONObject.toJSONString(decisionTableThreadPoolProperty));
        CustomerThreadPoolExecutor customerThreadPoolExecutor = new CustomerThreadPoolExecutor(decisionTableThreadPoolProperty);
        ExecutorService ttlExecutorService = TtlExecutors.getTtlExecutorService(customerThreadPoolExecutor);
        customerThreadPoolExecutor.allowCoreThreadTimeOut(decisionTableThreadPoolProperty.isAllowCoreThreadTimeOut());
        return ttlExecutorService;
    }
    @ConditionalOnProperty(name = "xdecision.decisionchallengethread.enable")
    @Bean(name = "decisionChallengeThreadPool")
    public ExecutorService decisionChallengeThreadPoolProperty(@Qualifier("decisionChallengeThreadPoolProperty") ThreadPoolExecutorConfig decisionChallengeThreadPoolProperty) {
        log.info("decisionChallengeThreadPoolProperty={}", JSONObject.toJSONString(decisionChallengeThreadPoolProperty));
        CustomerThreadPoolExecutor customerThreadPoolExecutor = new CustomerThreadPoolExecutor(decisionChallengeThreadPoolProperty);
        ExecutorService ttlExecutorService = TtlExecutors.getTtlExecutorService(customerThreadPoolExecutor);
        customerThreadPoolExecutor.allowCoreThreadTimeOut(decisionChallengeThreadPoolProperty.isAllowCoreThreadTimeOut());
        return ttlExecutorService;
    }

    @Bean(name = "batchThreadPool")
    @ConditionalOnProperty(name = "xdecision.batchthread.enable")
    public ExecutorService batchThreadPoolProperty(@Qualifier("batchThreadPoolProperty") ThreadPoolExecutorConfig batchThreadPoolProperty) {
        log.info("batchThreadPoolProperty={}", JSONObject.toJSONString(batchThreadPoolProperty));
        CustomerThreadPoolExecutor customerThreadPoolExecutor = new CustomerThreadPoolExecutor(batchThreadPoolProperty);
        ExecutorService ttlExecutorService = TtlExecutors.getTtlExecutorService(customerThreadPoolExecutor);
        customerThreadPoolExecutor.allowCoreThreadTimeOut(batchThreadPoolProperty.isAllowCoreThreadTimeOut());
        return ttlExecutorService;
    }

    @Bean(name = "reentryThreadPool")
    @ConditionalOnProperty(name = "xdecision.reentrythread.enable")
    public ExecutorService reentryThreadPool(@Qualifier("reentryThreadPoolPropertyProperty") ThreadPoolExecutorConfig reentryThreadPoolPropertyProperty) {
        log.info("reentryThreadPoolPropertyProperty={}", JSONObject.toJSONString(reentryThreadPoolPropertyProperty));
        CustomerThreadPoolExecutor customerThreadPoolExecutor = new CustomerThreadPoolExecutor(reentryThreadPoolPropertyProperty);
        ExecutorService ttlExecutorService = TtlExecutors.getTtlExecutorService(customerThreadPoolExecutor);
        customerThreadPoolExecutor.allowCoreThreadTimeOut(reentryThreadPoolPropertyProperty.isAllowCoreThreadTimeOut());
        return ttlExecutorService;
    }

    @Bean(name = "nodeLogThreadPool")
    @ConditionalOnProperty(name = "xdecision.nodelogthread.enable")
    public ExecutorService nodeLogThreadPoolPropertyProperty(@Qualifier("nodeLogThreadPoolPropertyProperty") ThreadPoolExecutorConfig reentryThreadPoolPropertyProperty) {
        log.info("nodeLogThreadPoolPropertyProperty={}", JSONObject.toJSONString(reentryThreadPoolPropertyProperty));
        CustomerThreadPoolExecutor customerThreadPoolExecutor = new CustomerThreadPoolExecutor(reentryThreadPoolPropertyProperty);
        ExecutorService ttlExecutorService = TtlExecutors.getTtlExecutorService(customerThreadPoolExecutor);
        customerThreadPoolExecutor.allowCoreThreadTimeOut(reentryThreadPoolPropertyProperty.isAllowCoreThreadTimeOut());
        return ttlExecutorService;
    }

    @Bean(name = "pulsarConsumerThreadPool")
    public ExecutorService pulsarConsumerThreadPool() {
        String poolName = "xpulsar-consumer-pool";
        CustomerThreadPoolExecutor customerThreadPoolExecutor = new CustomerThreadPoolExecutor(poolName);
        customerThreadPoolExecutor.allowCoreThreadTimeOut(true);
        return customerThreadPoolExecutor;
    }

    @Bean(name = "metadataCacheReloadThreadPool")
    public ExecutorService metadataCacheReloadThreadPool() {
        String poolName = "metadata-cache-pool";
        CustomerThreadPoolExecutor customerThreadPoolExecutor = new CustomerThreadPoolExecutor(poolName, new DefaultThreadFactory(poolName));
        customerThreadPoolExecutor.allowCoreThreadTimeOut(true);
        return customerThreadPoolExecutor;
    }

//    @ConditionalOnProperty(prefix = "xdecision", name = "xpulsar-thread")
//    @Bean(name = "xpulsarProcessorThreadPool")
//    public ExecutorService xpulsarProcessorThreadPool(@Qualifier("xpulsarThreadPoolPropertyProperty") ThreadPoolExecutorConfig xpulsarThreadPoolPropertyProperty) {
//        CustomerThreadPoolExecutor customerThreadPoolExecutor = new CustomerThreadPoolExecutor(xpulsarThreadPoolPropertyProperty);
//        ExecutorService ttlExecutorService = TtlExecutors.getTtlExecutorService(customerThreadPoolExecutor);
//        return ttlExecutorService;
//    }

//




}
